package logger

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"sync"
	"time"
)

type RateLimitedLogger struct {
	mu         sync.Mutex
	lastLogged map[string]time.Time
	interval   time.Duration
}

// NewRateLimitedLogger 创建带限流功能的日志记录器
func NewRateLimitedLogger(interval time.Duration) *RateLimitedLogger {
	return &RateLimitedLogger{
		lastLogged: make(map[string]time.Time),
		interval:   interval,
	}
}

// InitLogFile 初始化日志文件，每次运行时生成新的日志文件
func InitLogFile() (*os.File, error) {
	// 定义日志目录
	logDir := "./Log"

	// 检查目录是否存在，如果不存在则创建
	if _, err := os.Stat(logDir); os.IsNotExist(err) {
		err := os.MkdirAll(logDir, os.ModePerm)
		if err != nil {
			return nil, fmt.Errorf("无法创建日志目录: %v", err)
		}
	}

	// 获取当前日期
	currentDate := time.Now().Format("2006-1-2")

	// 获取日志文件名的最大编号
	logFileName, err := getNextLogFileName(logDir, currentDate)
	if err != nil {
		return nil, fmt.Errorf("无法生成日志文件名: %v", err)
	}

	// 创建或打开日志文件
	logFilePath := filepath.Join(logDir, logFileName)
	logFile, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("无法创建日志文件: %v", err)
	}

	// 设置日志输出到文件
	log.SetOutput(logFile)
	return logFile, nil
}

// getNextLogFileName 查找当前日期的日志文件并确定下一个编号
func getNextLogFileName(logDir, currentDate string) (string, error) {
	// 匹配类似 [2024-9-17]-1.log 的日志文件
	pattern := regexp.MustCompile(fmt.Sprintf(`^\[%s\]-(\d+)\.log$`, regexp.QuoteMeta(currentDate)))
	latestIndex := 0

	// 读取日志目录下的所有文件
	files, err := os.ReadDir(logDir)
	if err != nil {
		return "", fmt.Errorf("无法读取日志目录: %v", err)
	}

	// 遍历所有文件，找到符合当前日期的日志文件
	for _, file := range files {
		matches := pattern.FindStringSubmatch(file.Name())
		if len(matches) == 2 {
			index, err := strconv.Atoi(matches[1])
			if err == nil && index > latestIndex {
				latestIndex = index
			}
		}
	}

	// 生成新的日志文件名，编号递增
	nextIndex := latestIndex + 1
	return fmt.Sprintf("[%s]-%d.log", currentDate, nextIndex), nil
}

// 通用的日志输出函数
func logMessage(errMsg string, err error) {
	log.Printf("%s: %v ", errMsg, err)
}

// LogError 记录错误日志，无限流
func LogError(errMsg string, err error) {
	logMessage(errMsg, err)
}

// LogWithRateLimit 通过限流记录日志
func (r *RateLimitedLogger) LogWithRateLimit(errMsg string, err error) {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 获取上次记录时间
	lastTime, exists := r.lastLogged[errMsg]

	// 如果日志在设定的时间间隔内已记录，则跳过
	if exists && time.Since(lastTime) < r.interval {
		return
	}

	// 记录日志并更新上次记录时间
	logMessage(errMsg, err)
	r.lastLogged[errMsg] = time.Now()
}
